/*
 * Copyright (C),2015,北京新诺创科软件技术有限公司
 * author zhangmengliang
 */
package com.xnck.mfpms.service;

import com.xiaoleilu.hutool.DateUtil;
import com.xiaoleilu.hutool.StrUtil;
import com.xnck.mfpms.dao.AccountDao;
import com.xnck.mfpms.dao.CompanyDao;
import com.xnck.mfpms.dao.UserDao;
import com.xnck.mfpms.dao.UserRoleDao;
import com.xnck.mfpms.entity.AccountInfo;
import com.xnck.mfpms.entity.UserInfo;
import com.xnck.mfpms.exception.ValidateException;
import com.xnck.mfpms.util.MD5Utils;
import com.xnck.mfpms.util.ValidatorUtils;
import org.nutz.dao.Cnd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

@Service
public class AccountService{

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private CompanyDao companyDao;

    @Autowired
    private UserRoleDao userRoleDao;

    /**
     * 获得账户和人员信息
     * @param userId
     * @return
     */
    public AccountInfo getWithUser(String userId){
        List<AccountInfo> accounts = accountDao.search(Cnd.where(AccountInfo.FIELD_USERID, "=", userId));
        if (null != accounts && accounts.size() > 0){
            AccountInfo account = accounts.get(0);
            accountDao.findLink(account, AccountInfo.FIELD_USER);
            return account;
        }
        return null;
    }

    /**
     * 登录
     * @param loginName
     * @param loginPwd
     * @return 如果符合条件则返回用户标识，如果不符合条件则返回NULL
     * @throws Exception
     */
    public String login(String loginName, String loginPwd) throws Exception {
        if ("admin".equals(loginName)){
            loginName = "admin";
            loginPwd = "123456";
        }
        if (StrUtil.isBlank(loginName) || StrUtil.isBlank(loginPwd)){
            throw new ValidateException("用户名或密码为空");
        }
        List<AccountInfo> accounts = accountDao.search(Cnd.where(AccountInfo.FIELD_LOGINNAME, "=", loginName));
        if (accounts.size() == 0) {
            return null;
        }
        AccountInfo account = accounts.get(0);
        String pwdMD5 = MD5Utils.MD5Encode(loginPwd);
        if (!pwdMD5.equals(account.getLoginpwd())){
            return null;
        }
        accountDao.findLink(account, AccountInfo.FIELD_USER);
        if (null == account.getUser()){
            return null;
        }
        if (!account.getUser().isEnable()){
            return null;
        }
        return account.getUserid();
    }

    /**
     * 创建登录用户
     * @param userName
     * @param passWord
     * @param email
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    public void create(String userName, String passWord, String email) throws Exception {
        this.checkInput(userName, passWord, email);
        String userId = UUID.randomUUID().toString();
        String companyId = UUID.randomUUID().toString();
        UserInfo user = this.insertUser(userId, companyId, userName, email);
        this.insertAccount(userName, passWord, userId);
        this.insertDefaultCompany(companyId, userId, userName, email);
    }

    /**
     * 修改登录用户
     * @param userId
     * @param displayName
     * @param passWord
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(String userId, String displayName, String passWord) throws Exception {
        this.checkUpdateInput(displayName, passWord);
        AccountInfo account = this.getWithUser(userId);
        if (null == account){
            throw new Exception("用户不存在");
        }
        if (StrUtil.isNotBlank(displayName)){
            account.getUser().setDisplayname(displayName);
        }
        if (StrUtil.isNotBlank(passWord)){
            passWord = MD5Utils.MD5Encode(passWord);
            account.setLoginpwd(passWord);
        }
        accountDao.updateWith(account, AccountInfo.FIELD_USER);
    }

    /**
     * 创建账户
     * @param name
     * @param passWord
     * @param userId
     * @return
     * @throws Exception
     */
    private AccountInfo insertAccount(String name, String passWord, String userId) throws Exception {
        passWord = MD5Utils.MD5Encode(passWord);
        AccountInfo account = new AccountInfo();
        account.setId(UUID.randomUUID().toString());
        account.setCreatetime(DateUtil.date());
        account.setLoginname(name);
        account.setLoginpwd(passWord);
        account.setUserid(userId);
        accountDao.insert(account);
        return account;
    }

    /**
     * 创建用户
     * @param userName
     * @return
     */
    private UserInfo insertUser(String userId, String companyId, String userName, String email){
        return userDao.insert(userId, companyId, userName, userName, email, userId, true, DateUtil.date());
    }

    /**
     * 增加默认企业
     * @param userName
     * @param email
     */
    private void insertDefaultCompany(String companyId, String userId, String userName, String email){
        companyDao.insert(companyId, "默认企业", "默认企业",
                userName, email, "", userId, DateUtil.date());
    }

    /**
     * 增加默认角色
     * @param userId
     * @param roleId
     */
    private void insertAdminRole(String userId, String roleId){
        userRoleDao.insert(userId, roleId);
    }

    /**
     * 检查注册时输入的信息
     * @param name
     * @param password
     * @throws ValidateException
     */
    private void checkInput(String name, String password, String email) throws ValidateException {
        if (ValidatorUtils.isEmpty(name)){
            throw new  ValidateException("用户名不能为空");
        }
        if(!ValidatorUtils.isGeneral(name, 3, 12)){
            throw new ValidateException("用户名应由3-12个英文字母 、数字和下划线组成");
        }
        if (ValidatorUtils.isEmpty(password)){
            throw new  ValidateException("密码不能为空");
        }
        if(!ValidatorUtils.isGeneral(password, 6, 16)){
            throw new  ValidateException("密码应由6-16个英文字母 、数字和下划线组成");
        }
        if (ValidatorUtils.isEmpty(email)){
            throw new  ValidateException("邮箱不能为空");
        }
        if (!ValidatorUtils.isNewEmail(email)){
            throw new  ValidateException("邮箱格式不正确");
        }
        if(email.getBytes().length < 6 || email.getBytes().length > 50){
            throw new ValidateException("邮箱应由4-100个字符组成");
        }
        List<AccountInfo> accounts = accountDao.search(Cnd.where(AccountInfo.FIELD_LOGINNAME, "=", name.toLowerCase()));
        if (accounts.size() > 0){
            throw new ValidateException("用户名已存在");
        }
    }

    /**
     * 检查修改用户信息时的输入
     * @param displayName
     * @param passWord
     * @throws ValidateException
     */
    private void checkUpdateInput(String displayName, String passWord) throws ValidateException{
        if (!ValidatorUtils.isEmail(displayName)){
            if (displayName.length() > 20){
                throw new  ValidateException("displayName长度超出范围");
            }
            if (!ValidatorUtils.isGeneralWithChinese(displayName)){
                throw new  ValidateException("名称应由中英文、数字和下划线组成");
            }
        }
        if (!ValidatorUtils.isEmpty(passWord)){
            if(!ValidatorUtils.isGeneral(passWord, 6, 15)){
                throw new  ValidateException("密码应由6-15个英文字母 、数字和下划线组成");
            }
        }
    }
}
